//
//  UIAlertController+YCTools.m
//  Pods
//
//  Created by Apple on 2022/11/5.
//

#import "UIAlertController+YCTools.h"
#import <objc/runtime.h>

#define AlertActionDefaultFont    [UIFont systemFontOfSize:18]
#define AlertActionDefaultColor   [UIColor colorWithRed:26/255.0 green:26/255.0 blue:26/255.0 alpha:1.0]

@implementation UIAlertActionConfig

+ (instancetype)configWithText:(NSString *)text font:(UIFont *)font color:(UIColor *)color {
    UIAlertActionConfig *model = [[UIAlertActionConfig alloc] init];
    
    model.text  = text;
    model.font  = font;
    model.color = color;
    
    return model;
}

+ (instancetype)configWithText:(NSString *)text color:(UIColor *)color {
    return [self configWithText:text font:nil color:color];
}

+ (instancetype)configWithText:(NSString *)text {
    return [self configWithText:text font:nil color:nil];
}

- (UIColor *)defaultColor {
    return AlertActionDefaultColor;
}

- (UIFont *)defaultFont {
    return AlertActionDefaultFont;
}

@end






@implementation NSString (UIAlertActionConfig_Ext)

- (UIAlertActionConfig *)alertConfigWithColor:(UIColor *)color {
    return [UIAlertActionConfig configWithText:self font:nil color:color];
}
- (UIAlertActionConfig *)alertConfigWithFont:(UIFont *)font color:(UIColor *)color {
    return [UIAlertActionConfig configWithText:self font:font color:color];
}

@end






@implementation UIAlertAction (CustomConfig)

- (UILabel *)theLabel {
    UIView *representer = [self valueForKey:@"_representer"];
    UILabel *label = [representer valueForKey:@"label"];
    
    return label;
}

- (UIFont *)fc_font {
    return [self theLabel].font;
}

- (void)setFc_font:(UIFont *)fc_font {
    if (fc_font) {
        [self theLabel].font = fc_font;
    }
}

- (void)updateFont {
    self.fc_font = self.fc_tempFont;
}

static const void *FCKey_UIAlertActionFont = &FCKey_UIAlertActionFont;

- (UIFont *)fc_tempFont {
    return objc_getAssociatedObject(self, FCKey_UIAlertActionFont);
}

- (void)setFc_tempFont:(UIFont *)fc_tempFont {
    objc_setAssociatedObject(self, FCKey_UIAlertActionFont, fc_tempFont, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

static const void *FCKey_UIAlertActionCusView = &FCKey_UIAlertActionCusView;

- (UIView *)fc_cusView {
    return objc_getAssociatedObject(self, FCKey_UIAlertActionCusView);
}

- (void)setFc_cusView:(UIView *)fc_cusView {
    objc_setAssociatedObject(self, FCKey_UIAlertActionCusView, fc_cusView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end


@implementation UIAlertController (YCTools)

+ (NSString *)stringFrom:(id)obj {
    if ([obj isKindOfClass:[NSString class]]) {
        return (NSString *)obj;
    } else if ([obj isKindOfClass:[UIAlertActionConfig class]]) {
        return [obj valueForKey:@"text"];
    } else if ([obj isKindOfClass:[UIView class]]) {
        return @"";
    } else {
        return nil;
    }
}

- (void)config:(NSString *)key withModel:(id)aModel {
    
    if ([aModel isKindOfClass:[NSString class]]) {
        
        return;
        
    } else if ([aModel isKindOfClass:[UIAlertActionConfig class]]) {
        
        UIAlertActionConfig *model = (UIAlertActionConfig *)aModel;
        
        if (model.text.length > 0 && key) {
            
            NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
            
            //字体
            if (model.font) {
                [attributes setObject:model.font forKey:NSFontAttributeName];
            }
            //颜色
            if (model.color) {
                [attributes setObject:model.color forKey:NSForegroundColorAttributeName];
            }
            if (attributes.count > 0) {
                NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:model.text?:@"" attributes:attributes];
                [self setValue:attrStr forKey:key];
            }
        }
    }
}

- (void)configTitle:(id)title {
    [self config:@"attributedTitle" withModel:title];
}

- (void)configMessage:(id)message {
    [self config:@"attributedMessage" withModel:message];
}

- (void)configAction:(UIAlertAction *)action withModel:(id)aModel {
    
    if (aModel) {
        //设置默认颜色
        if ([aModel isKindOfClass:[NSString class]]) {
            [action setValue:AlertActionDefaultColor forKey:@"titleTextColor"];
        }
        //设置自定义颜色
        else if ([aModel isKindOfClass:[UIAlertActionConfig class]]) {
            
            UIAlertActionConfig *model = (UIAlertActionConfig *)aModel;
            
            //颜色
            [action setValue:(model.color ? model.color : model.defaultColor) forKey:@"titleTextColor"];
            
            //字体 - 此时视图还未生成，所以先存下套设置的字体，后续寻找时机再设置
            action.fc_tempFont = (model.font ? model.font : model.defaultFont);
            
        }
        //自定义视图
        else if ([aModel isKindOfClass:[UIView class]]) {
            
            action.fc_cusView = aModel;
        }
    }
}



+ (instancetype)alertControllerWithStyle:(UIAlertControllerStyle)style
                                   title:(id)title
                                 message:(id)message
                           fieldSettings:(void(^)(UITextField *textField))fieldSettings
                                  cancel:(id)cancel
                                  others:(NSArray *)others
                                  action:(void (^)(NSInteger index, NSString *title, NSString *text))action
{
    UIAlertController *alert =
    [UIAlertController alertControllerWithTitle:[self stringFrom:title]
                                        message:[self stringFrom:message]
                                 preferredStyle:style];
    
    
    //设置 title、message 的 字体、颜色
    [alert configTitle:title];
    [alert configMessage:message];
    
    
    //添加输入框
    BOOL textFieldEnable = (style == UIAlertControllerStyleAlert && fieldSettings);
    //  注意：UIAlertControllerStyleAlert 才能添加输入框
    if (textFieldEnable) {
        [alert addTextFieldWithConfigurationHandler:fieldSettings];
    }
    
    
    //添加选项按钮
    if (others && [others isKindOfClass:[NSArray class]]) {
        
        id model                = nil;
        NSString *str           = nil;
        UIAlertAction *anAction = nil;
        
        for (NSInteger i = 0; i < others.count; i ++) {
            
            model    = others[i];
            str      = [self stringFrom:model];
            anAction =
            [UIAlertAction actionWithTitle:str style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull act) {
                if (action) {
                    NSString *text = nil;
                    if (textFieldEnable) {
                        text = alert.textFields.firstObject.text;
                    }
                    action(i, str, text);
                }
                [alert didClickAction];
            }];
            [alert configAction:anAction withModel:model];
            [alert addAction:anAction];
        }
    }
    
    
    //添加“取消”按钮
    NSString *cancelTitle = [self stringFrom:cancel];
    if (cancelTitle == nil) {
        cancelTitle = @"取消";
    }
    UIAlertAction *cancelAction =
    [UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull act) {
        if (action) {
            action(-1, cancelTitle, nil);
        }
        [alert didClickAction];
    }];
    [alert configAction:cancelAction withModel:cancel];
    [alert addAction:cancelAction];
    
    return alert;
}

- (void)didClickAction {
    //点击某个item后，置空所有 item 的代码块 handler
    for (UIAlertAction *action in self.actions) {
        [action setValue:nil forKey:@"handler"];
    }
}

#pragma mark - Alert
+ (instancetype)alertWithTitle:(id)title
                       message:(id)message
                 fieldSettings:(void(^)(UITextField *textField))fieldSettings
                        cancel:(id)cancel
                        others:(NSArray *)others
                        action:(void (^)(NSInteger, NSString *, NSString *))action
{
    return [self alertControllerWithStyle:UIAlertControllerStyleAlert
                                    title:title
                                  message:message
                            fieldSettings:fieldSettings
                                   cancel:cancel
                                   others:others
                                   action:action];
}

+ (instancetype)alertWithTitle:(id)title
                       message:(id)message
                        cancel:(id)cancel
                        others:(NSArray *)others
                        action:(void (^)(NSInteger index, NSString *title))action
{
    return [self alertWithTitle:title
                        message:message
                  fieldSettings:nil
                         cancel:cancel
                         others:others
                         action:^(NSInteger index, NSString *title, NSString *text)
            {
                if (action) {
                    action(index, title);
                }
            }];
}

#pragma mark - ActionSheet
+ (instancetype)sheetWithTitle:(id)title
                       message:(id)message
                        cancel:(id)cancel
                        others:(NSArray *)others
                        action:(void (^)(NSInteger index, NSString *title))action
{
    return [self alertControllerWithStyle:UIAlertControllerStyleActionSheet
                                    title:title
                                  message:message
                            fieldSettings:nil
                                   cancel:cancel
                                   others:others
                                   action:^(NSInteger index, NSString *title, NSString *text)
            {
                if (action) {
                    action(index, title);
                }
            }];
}

@end
